;; _travel_gen  'data|'method|'index='body|'para|defined-statement

(load "cn-cond-merge.lisp")

(defun tr-datap(data-)
  (or (eql data- 'data) (eql data- '数据)))
(defun tr-methodp(method-)
  (or (eql method- 'method) (eql data- '子项方法)))
(defun tr-indexp(index-)
  (or (eql index- 'index) (eql index- '子项变量)))

(defun _travel_gen(ll loc-type merge-list &optional (body-num 0))
  (let ((len (length merge-list))(data- (nth 0 (nth 0 merge-list)))(data-v (nth 1 (nth 0 merge-list)))
	(method- (nth 0 (nth 1 merge-list)))(method-v (nth 1 (nth 1 merge-list)))(index- (nth 0 (nth 2 merge-list)))
	(index-v (nth 1 (nth 2 merge-list))))
    (if (and (> len 0) (< len 4))
	(cond ((and (tr-datap data-)(tr-methodp method-)(tr-indexp index-))
	       (_edit ll loc-type `((body (travel ,data-v ,method-v ,index-v ,(get-loc ll loc-type body-num)) ,body-num))))
	      
	       (t (format t "遍历语句的归并列表不符合规则。[~a]~%" merge-list)))
	(format t "遍历语句的归并列表元素个数非法。[~a]~%" len))))
(defmacro travel(data method index &body body)
  (let ((m-val (gensym))(fn (gensym))(fn-par (gensym)))
  `(if (atom ,method)
       (cond ((typep ,data 'list)
	  (cond ((eql ,method 'for-child)
		 (dolist (,index ,data) ,@body))
		((eql ,method 'for-index)
		 (dotimes (,index (length ,data)) ,@body))
		((eql ,method 'for-atom)
		 (travel-list ,data ,index ,@body))
		(t (format t "未定义的列表方法。[~a]~%" ,method))))
	 ((typep ,data 'sequence)
	  (cond ((eql ,method 'for-index)
		 (dotimes (,index (length ,data)) ,@body))
		(t (format t "未定义的序列方法。[~a]~%" ,method))))
	 (t (format t "未定义的数据类型。")))
       (progn (if (atom (car ,method))(setf ,m-val (car ,method)))
	      (if (atom (cadr ,method))(setf ,fn (cadr ,method) ,fn-par nil)
		  (if (consp (cadr ,method))(setf ,fn (car (cadr ,method)) ,fn-par (cadr (cadr ,method)))))
	      (if (eql ,m-val 'for-atom) (travel-other ,fn ,fn-par ,data ,index ,@body))))))
       
(defmacro travel-list(data index &body body)
  (let ((fn (gensym)))
    `(let ((,index ,data)(,fn (lambda(,index) ,@body)))
       (tr-list ,index ,fn))))
(defun tr-list(l fn)
  (if (null l) nil
      (if (atom l) (funcall fn l)
	  (cons (tr-list (car l) fn)(tr-list (cdr l) fn)))))
(defmacro travel-other(fn fn-par data index &body body)
  (let ((f (gensym))(func-par (gensym)))
    `(let ((,index ,data)(,f (lambda(,index) ,@body)))
       (setf ,func-par (append ,fn-par (list ,index ,f)))
       ;(format t "par=[~a]~%" ,func-par)
       (apply ,fn ,func-par))))
(defun range(i j &optional k)
  (let ((l nil))
    (if (null k) (setf k 1))
    (do ((ii i (+ ii k)))
	((> ii j) (reverse l))
      (push ii l))))
	
(defun list-range(data i j &optional k)
  (let ((l nil))
    (if (null k) (setf k 1))
     (do ((ii i (+ ii k)))
	((or (> ii j) (>= ii (length data))) (reverse l))
      (push (nth ii data) l))))
